package chpn.id.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.params.SetParams;

/**
 * Redis工具类，封装Redis操作
 */
public class RedisUtil {
    // Redis连接池
    private static JedisPool jedisPool;

    // 缓存过期时间（2分钟）
    private static final int DEFAULT_EXPIRE_SECONDS = 120;

    static {
        initPool();
    }

    /**
     * 初始化Redis连接池
     */
    private static void initPool() {
        // 初始化Redis连接池
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(10);
        config.setMaxIdle(5);
        config.setMinIdle(1);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);

        // 默认连接本地Redis，可以通过系统属性或环境变量配置
        String redisHost = System.getProperty("redis.host", "localhost");
        int redisPort = Integer.parseInt(System.getProperty("redis.port", "6379"));
        String redisPassword = System.getProperty("redis.password", null);

        if (redisPassword != null && redisPassword.isEmpty()) {
            redisPassword = null;
        }

        jedisPool = new JedisPool(config, redisHost, redisPort, 2000, redisPassword);
    }

    /**
     * 获取Jedis资源
     */
    public static Jedis getJedisResource() {
        try {
            return jedisPool.getResource();
        } catch (Exception e) {
            System.err.println("获取Redis连接失败: " + e.getMessage());
            return null;
        }
    }

    /**
     * 关闭Redis连接池
     */
    public static void closePool() {
        if (jedisPool != null && !jedisPool.isClosed()) {
            jedisPool.close();
        }
    }

    /**
     * 设置键值对，如果键不存在
     *
     * @param key 键
     * @param value 值
     * @param expireSeconds 过期时间（秒）
     * @return 是否设置成功
     */
    public static boolean setIfNotExists(String key, String value, int expireSeconds) {
        try (Jedis jedis = getJedisResource()) {
            if (jedis == null) {
                return false;
            }

            String result = jedis.set(key, value, SetParams.setParams().nx().ex(expireSeconds));
            return result != null && result.equals("OK");
        } catch (Exception e) {
            System.err.println("Redis setIfNotExists操作异常: " + e.getMessage());
            return false;
        }
    }

    /**
     * 设置键值对，如果键不存在，使用默认过期时间
     *
     * @param key 键
     * @param value 值
     * @return 是否设置成功
     */
    public static boolean setIfNotExists(String key, String value) {
        return setIfNotExists(key, value, DEFAULT_EXPIRE_SECONDS);
    }

    /**
     * 获取键对应的值
     *
     * @param key 键
     * @return 值，如果键不存在或发生异常则返回null
     */
    public static String get(String key) {
        try (Jedis jedis = getJedisResource()) {
            if (jedis == null) {
                return null;
            }

            return jedis.get(key);
        } catch (Exception e) {
            System.err.println("Redis get操作异常: " + e.getMessage());
            return null;
        }
    }

    /**
     * 删除键
     *
     * @param key 键
     * @return 是否删除成功
     */
    public static boolean delete(String key) {
        try (Jedis jedis = getJedisResource()) {
            if (jedis == null) {
                return false;
            }

            return jedis.del(key) > 0;
        } catch (Exception e) {
            System.err.println("Redis delete操作异常: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 删除所有以指定前缀开头的键
     *
     * @param keyPrefix 键前缀
     * @return 删除的键数量
     */
    public static long deleteByPrefix(String keyPrefix) {
        try (Jedis jedis = getJedisResource()) {
            if (jedis == null) {
                return 0;
            }
            
            // 使用KEYS命令查找所有匹配的键
            // 注意：在生产环境中应谨慎使用KEYS命令，因为它可能会阻塞Redis
            // 但在测试环境中，这是一个简单有效的方法
            String pattern = keyPrefix + "*";
            long count = 0;
            
            for (String key : jedis.keys(pattern)) {
                jedis.del(key);
                count++;
            }
            
            return count;
        } catch (Exception e) {
            System.err.println("Redis deleteByPrefix操作异常: " + e.getMessage());
            return 0;
        }
    }

    /**
     * 设置键值对，如果键存在则更新
     *
     * @param key 键
     * @param value 值
     * @param expireSeconds 过期时间（秒）
     * @return 是否设置成功
     */
    public static boolean set(String key, String value, int expireSeconds) {
        try (Jedis jedis = getJedisResource()) {
            if (jedis == null) {
                return false;
            }

            String result = jedis.set(key, value, SetParams.setParams().ex(expireSeconds));
            return result != null && result.equals("OK");
        } catch (Exception e) {
            System.err.println("Redis set操作异常: " + e.getMessage());
            return false;
        }
    }

    /**
     * 设置键值对，如果键存在则更新，使用默认过期时间
     *
     * @param key 键
     * @param value 值
     * @return 是否设置成功
     */
    public static boolean set(String key, String value) {
        return set(key, value, DEFAULT_EXPIRE_SECONDS);
    }

    /**
     * 获取键对应的长整型值
     *
     * @param key 键
     * @param defaultValue 默认值，如果键不存在或发生异常则返回此值
     * @return 长整型值
     */
    public static long getLong(String key, long defaultValue) {
        try (Jedis jedis = getJedisResource()) {
            if (jedis == null) {
                return defaultValue;
            }

            String value = jedis.get(key);
            if (value == null) {
                return defaultValue;
            }

            return Long.parseLong(value);
        } catch (Exception e) {
            System.err.println("Redis getLong操作异常: " + e.getMessage());
            return defaultValue;
        }
    }
}
